﻿// Copyright © 2011 Paul Vanukoff (pvanukoff@gmail.com)

using System;
using System.IO;
using Bravura.Contracts.PluginTypes;
using Bravura.Core.PluginLib;
using Bravura.Native.PluginBase;

namespace Bravura.Native.Plugins.Sends
{
	public class DiskSend : Send, ISend
	{
		#region Fields

		private FileStream _stream = null;
		private int _channelCount = 1;

		#endregion

		#region Properties

		public string FilenameBase
		{
			get;
			set;
		}

		public string FilenameExt
		{
			get;
			set;
		}

		public int ChannelCount
		{
			get { return _channelCount; }
			set { _channelCount = value; }
		}

		#endregion

		public DiskSend(IAudioPluginHost host, int sampleRate) : base(host, sampleRate)
		{
			this.FilenameBase = "output";
			this.FilenameExt = "raw";
			this.ChannelCount = 1;
		}

		#region Open / Process / Close

		public override void Open()
		{
			_stream = null;
			
			if (!_host.GetOutputPath().Exists)
			{
				_host.GetOutputPath().Create();
			}
			
			_stream = File.Create(string.Format(@"{0}\{1}.{2}", _host.GetOutputPath().FullName, FilenameBase, FilenameExt));
		}

		public override void Process(int count)
		{
			if (_stream != null)
			{
				if (_channelCount == 1) // mono
				{
					double[] buff0 = GetInputBuffer(0).Read(count);

					// write each value
					for (int i = 0; i < count; i++)
					{
						double dval = _gain * buff0[i];

						if (dval < -1.0) dval = -1.0;
						else
						if (dval > +1.0) dval = +1.0;

						Int16 val = (Int16)(32767.5 * dval);
						byte[] bytes = BitConverter.GetBytes(val);
						_stream.Write(bytes, 0, 2);
					}
				}
				else // stereo
				{
					double[] buff0 = GetInputBuffer(0).Read(count);
					double[] buff1 = GetInputBuffer(1).Read(count);

					// write each value
					for (int i = 0; i < count; i++)
					{
						double dval0 = _gain * buff0[i];

						if (dval0 < -1.0) dval0 = -1.0;
						else
						if (dval0 > +1.0) dval0 = +1.0;

						Int16 val0 = (Int16)(32767.5 * dval0);
						byte[] bytes0 = BitConverter.GetBytes(val0);
						_stream.Write(bytes0, 0, 2);

						double dval1 = _gain * buff1[i];

						if (dval1 < -1.0) dval1 = -1.0;
						else
						if (dval1 > +1.0) dval1 = +1.0;

						Int16 val1 = (Int16)(32767.5 * dval1);
						byte[] bytes1 = BitConverter.GetBytes(val1);
						_stream.Write(bytes1, 0, 2);
					}
				}

				// flush to disk
				_stream.Flush();
			}
		}

		public override void Close()
		{
			if (_stream != null)
			{
				_stream.Close();
				_stream = null;
			}
		}

		#endregion
	}
}
